import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

class Bubble extends StatelessWidget {
  late double? _left;
  late double? _right;
  late double? arrowWidth; //箭头宽度
  late double? arrowHeight; //箭头高度
  late double? minHeight; //内容最小高度
  late double? minWidth; //内容最小宽度
  late BubbleDirection? direction;
  late Radius? borderRadius;
  late Widget? child;
  late BoxDecoration? decoration;
  late Color? color;
  late EdgeInsetsGeometry? padding;
  late EdgeInsetsGeometry? margin;
  late BoxConstraints? constraints;
  late double? width;
  late double? height;
  late Alignment? alignment;
  Bubble(
      {Key? key,
      this.direction = BubbleDirection.left,
      this.borderRadius,
      this.child,
      this.decoration,
      this.color,
      this.padding,
      this.margin,
      this.constraints,
      this.arrowHeight,
      this.width,
      this.height,
      this.alignment}) {
    arrowWidth ??= 5.w;
    arrowHeight ??= arrowWidth! * 2;
    minHeight ??= 15.h;
    minWidth ??= 20.w;
    if (direction == BubbleDirection.left) {
      _left = arrowWidth;
      _right = 0;
    } else {
      _right = arrowWidth;
      _left = 0;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      color: Colors.transparent,
      child: ClipPath(
        clipper: _BubbleClipper(
            direction!,
            borderRadius ?? const Radius.circular(5.0),
            arrowWidth!,
            arrowHeight!,
            minHeight!,
            minWidth!),
        child: Container(
          alignment: alignment,
          width: width,
          height: height,
          constraints: (constraints ?? const BoxConstraints())
              .copyWith(minHeight: minHeight, minWidth: minWidth),
          margin: margin,
          decoration: decoration,
          color: color,
          padding: EdgeInsets.fromLTRB(_left!, 0.0, _right!, 0.0)
              .add(padding ?? const EdgeInsets.fromLTRB(7.0, 5.0, 7.0, 5.0)),
          child: child,
        ),
      ),
    );
  }
}

///方向
enum BubbleDirection { left, right }

class _BubbleClipper extends CustomClipper<Path> {
  final BubbleDirection direction;
  final Radius radius;
  final double arrowWidth; //箭头宽度
  final double arrowHeight; //箭头高度
  final double minHeight; //内容最小高度
  final double minWidth; //内容最小宽度
  _BubbleClipper(this.direction, this.radius, this.arrowWidth, this.arrowHeight,
      this.minHeight, this.minWidth);

  @override
  Path getClip(Size size) {
    final path = Path();
    final path2 = Path();
    final centerPoint = (size.height / 2).clamp(minHeight / 2, minHeight / 2);

    if (direction == BubbleDirection.left) {
      //绘制左边三角形
      path.moveTo(0, centerPoint);
      path.lineTo(arrowWidth, centerPoint - arrowHeight / 2);
      path.lineTo(arrowWidth, centerPoint + arrowHeight / 2);
      path.close();
      //绘制矩形
      path2.addRRect(RRect.fromRectAndRadius(
          Rect.fromLTWH(arrowWidth, 0, (size.width - arrowWidth), size.height),
          radius));
      //合并
      path.addPath(path2, const Offset(0, 0));
    } else {
      //绘制右边三角形
      path.moveTo(size.width, centerPoint);
      path.lineTo(size.width - arrowWidth, centerPoint - arrowHeight / 2);
      path.lineTo(size.width - arrowWidth, centerPoint + arrowHeight / 2);
      path.close();
      //绘制矩形
      path2.addRRect(RRect.fromRectAndRadius(
          Rect.fromLTWH(0, 0, (size.width - arrowWidth), size.height), radius));
      //合并
      path.addPath(path2, const Offset(0, 0));
    }
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) {
    return false;
  }
}
